package com.database.objects;

import static com.load.utils.DateUtil.validateDate;

import java.util.*;

import javax.persistence.*;

import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.io.*;

import com.google.common.collect.*;
import com.load.utils.*;
import com.metrics.objects.*;

@Embeddable
public class VersionRepository extends Repository {

	private static final long serialVersionUID = 3244921152417626913L;

	public static final List<Type> TYPES = Lists.newArrayList(Type.COMMIT, Type.FILE_OO, Type.FILE_NO_OO, Type.CLASS, Type.METHOD, Type.LINE_OO);

	public static final List<Status> STATUS = Lists.newArrayList(Status.ADD, Status.MODIFY, Status.DELETE, Status.TOTAL);

	public static final List<Metric> METRICS = Lists.newArrayList(Metric.COUNTER_OF_ELEMENTS, Metric.CYCLOMATIC_COMPLEXITY, Metric.CONSTANTINE_COHESION);

	@Column(name = "ver_url", nullable = false)
	private String url = "";

	@Column(name = "ver_login", nullable = false)
	private String login = "";

	@Column(name = "ver_password", nullable = false)
	private String password = "";

	@Column(name = "ver_start_date_load", nullable = false)
	private String startDateLoad = "";

	@Column(name = "ver_finish_date_load", nullable = false)
	private String finishDateLoad = "";

	@Enumerated(EnumType.STRING)
	@Column(name = "ver_type", nullable = false)
	private Type type = Type.UNKNOWN;

	@Transient
	private String startDate;

	@Transient
	private SVNRepository svnRepository;

	@Transient
	private List<SVNLogEntry> entries = new ArrayList<SVNLogEntry>();

	@Transient
	private List<SVNLogEntry> allEntries = new ArrayList<SVNLogEntry>();

	public VersionRepository() {

	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getStartDate() {
		return startDate;
	}

	public String getStartDateLoad() {
		return startDateLoad;
	}

	public void setStartDateLoad(String startDateLoad) {
		this.startDateLoad = startDateLoad;
	}

	public String getFinishDateLoad() {
		return finishDateLoad;
	}

	public void setFinishDateLoad(String finishDateLoad) {
		this.finishDateLoad = finishDateLoad;
	}

	public Type getType() {
		return type;
	}

	public void setType(Type type) {
		this.type = type;
	}

	public SVNRepository getSvnRepository() {
		return svnRepository;
	}

	public void setSvnRepository() throws SVNException {
		svnRepository = SVNUtil.configureRepository(url, login, password);
	}

	public List<SVNLogEntry> getEntries() {
		return entries;
	}

	public List<SVNLogEntry> getAllEntries() {
		return allEntries;
	}

	public void setEntries() throws SVNException {
		List<SVNLogEntry> entries = new ArrayList<SVNLogEntry>();
		Collection<?> svnEntries = SVNUtil.getEntries(svnRepository);

		startDate = DateUtil.formatString(((SVNLogEntry) svnEntries.iterator().next()).getDate());
		for (Object svnEntry : svnEntries) {
			SVNLogEntry entry = (SVNLogEntry) svnEntry;
			String date = DateUtil.formatString(entry.getDate());

			boolean dateIsAfterStart = startDateLoad == null || startDateLoad.equals("") || startDateLoad.compareTo(date) <= 0;
			boolean dateIsBeforeFinish = finishDateLoad == null || finishDateLoad.equals("") || finishDateLoad.compareTo(date) >= 0;

			if (dateIsAfterStart && dateIsBeforeFinish) {
				entries.add(entry);
			}
			allEntries.add(entry);
		}
		this.entries = entries;
	}

	public float getNumEntries() {
		return entries.size();
	}

	public void processUrl() {
		url = url.endsWith("/") ? url.substring(0, url.length() - 1) : url;
	}

	public boolean isValidateUrl() {
		try {
			String urlToValidate = url.endsWith("/") ? url.substring(0, url.length() - 1) : url;
			SVNURL.parseURIDecoded(urlToValidate);
			return true;
		} catch (SVNException e) {
			e.printStackTrace();
			return false;
		}
	}

	public boolean isValidateStartDate() {
		boolean isBlankStartDate = startDateLoad == null || startDateLoad.equals("");
		return isBlankStartDate || validateDate(startDateLoad);
	}

	public boolean isValidateFinishDate() {
		boolean isBlankFinishDate = finishDateLoad == null || finishDateLoad.equals("");
		return isBlankFinishDate || validateDate(finishDateLoad);
	}

	@Override
	public boolean isVersionRepository() {
		return true;
	}

	@Override
	public boolean isTrackerRepository() {
		return false;
	}

	@Override
	public List<Type> getTypes() {
		return TYPES;
	}

	@Override
	public List<Status> getStatus() {
		return STATUS;
	}

	@Override
	public List<Metric> getMetrics() {
		return METRICS;
	}

}